<?php

namespace app\admin\logic;

use app\admin\model\Coursepaper;
use app\admin\model\Coursequestioncategory;
use app\admin\model\Question;
use app\admin\model\Questioncategory;
use app\common\exception\BusinessException;
use app\common\model\CourseQuestionBackground;
use app\common\service\ExcelDataToQuestionJsonService;

class ImportQuestionLogic
{
    public function import($course_id, $extend_id, $excelFile, $uid = 0)
    {
        // 将Excel转换为标准数据,格式如下:
        /**
         * {
         * "questionType": 1,
         * "questionBackground": "",
         * "questionAsk": "食醋是什么味道的？",
         * "questionOption": {
         * "A": "酸",
         * "B": "甜",
         * "C": "苦",
         * "D": "辣",
         * "E": "",
         * "F": "",
         * "G": "",
         * "H": ""
         * },
         * "correctOption": "A",
         * "explanation": "",
         * "questionCategoryName": "",
         * "questionDifficulty": ""
         * }
         */
        $allQuestionData = (new ExcelDataToQuestionJsonService())->invoke($excelFile);
        foreach ($allQuestionData as $question) {
            $this->saveQuestion($course_id, $extend_id, $question, $uid);
        }
        // 更新章节题目数量
        $this->updateChapterQuestionCount($course_id, $extend_id);
    }


    public function cateImport($course_id, $category_id, $excelFile, $uid = 0)
    {
        // 读取分类信息
        $model = new Coursequestioncategory();
        $categoryInfo = $model->find($category_id);
        if (!$categoryInfo) {
            throw new BusinessException('顶级分类不存在');
        }

        // 将Excel转换为标准数据
        $allQuestionData = (new ExcelDataToQuestionJsonService())->invoke($excelFile);

        // 定义检查的键
        $keysToCheck = $categoryInfo['is_multi_level'] == 1 ? ['category_1', 'category_2'] : ['category_1'];
        $keysToCheckMessages = $categoryInfo['is_multi_level'] == 1 ? '多级分类必须填写表格中的二级分类和三级分类' : '普通分类必须填写表格中的二级分类';

        // 执行检查函数
        $checkResults = checkKeyValues($allQuestionData, $keysToCheck);
        if (!$checkResults) {
            throw new BusinessException($keysToCheckMessages);
        }

        if ($categoryInfo['is_multi_level'] == 1) {
            $this->saveCateQuestionByCategory($course_id, $category_id, $allQuestionData, $uid);
        } else {
            $this->saveCateQuestionByPaper($course_id, $category_id, $allQuestionData, $uid);
        }
    }

    private function saveCateQuestionByCategory($course_id, $category_id, $allQuestionData, $uid)
    {
        // 01.解析分类
        $waitCreateCateDict = [];
        foreach ($allQuestionData as $question) {

            // 提取分类
            $category_1 = trim($question['category_1']); // 二级分类名称
            $category_2 = trim($question['category_2']); // 三级级分类名称

            // 保存分类结构
            $waitCreateCateDict[$category_1][$category_2] = true;
        }

        // 02.创建分类
        $model = new Coursequestioncategory();
        $index = 0;
        $tag_id = 30;
        $time = time();
        $allCateNameIdMap = [];
        foreach ($waitCreateCateDict as $category_1 => $category_2Dict) {

            $index++;

            // 创建一级分类
            $where1 = ['course_id' => $course_id, 'level' => 2, 'pid' => $category_id, 'tag_id' => $tag_id, 'name' => $category_1];
            $category_1_id = $model->where($where1)->value('id', 0);
            $saveData = [
                'course_id' => $course_id,
                'name' => $category_1,
                'icon' => '',
                'weigh' => 1000 - $index,
                'level' => 2,
                'tag_id' => $tag_id,
                'pid' => $category_id,
                'create_time' => $time,
                'update_time' => $time,
            ];
            if ($category_1_id) {
                $model->where($where1)->update($saveData);
            } else {
                $category_1_id = $model->insertGetId($saveData);
            }

            // 创建二级分类
            $nextIndex = 1;
            foreach ($category_2Dict as $category_2 => $v) {
                $where2 = ['course_id' => $course_id, 'level' => 3, 'pid' => $category_1_id, 'tag_id' => $tag_id, 'name' => $category_2];
                $category_2_id = $model->where($where2)->value('id', 0);
                $saveSectionData = [
                    'course_id' => $course_id,
                    'name' => $category_2,
                    'icon' => '',
                    'weigh' => 1000 - $nextIndex,
                    'level' => 3,
                    'tag_id' => $tag_id,
                    'pid' => $category_1_id,
                    'create_time' => $time,
                    'update_time' => $time,
                ];
                if ($category_2_id) {
                    $model->where($where1)->update($saveSectionData);
                } else {
                    $category_2_id = $model->insertGetId($saveSectionData);
                }

                // 创建试卷
                $paperWhere = [
                    'course_id' => $course_id,
                    'tag_id' => $tag_id,
                    'category_id' => $category_2_id,
                ];
                $paperModel = new Coursepaper();
                $paperId = $paperModel->where($paperWhere)->value('id', 0);
                $paperSaveData = [
                    'name' => $category_2,
                    'tag_id' => $tag_id,
                    'course_id' => $course_id,
                    'category_id' => $category_2_id,
                    'sort' => 1000 - $nextIndex,
                    'create_time' => $time,
                    'update_time' => $time,
                ];
                if ($paperId) {
                    $paperModel->where($paperWhere)->update($paperSaveData);
                } else {
                    $paperId = $paperModel->insertGetId($paperSaveData);
                }

                // 记录试卷名称和编号
                $allCateNameIdMap[$category_1 . $category_2] = $paperId;
            }
        }

        // 03.循环导入试卷
        foreach ($allQuestionData as $question) {
            // 提取分类
            $category_1 = trim($question['category_1']);
            $category_2 = trim($question['category_2']);

            // 提取试卷编号
            $paperId = $allCateNameIdMap[$category_1 . $category_2];

            // 创建题目
            $this->saveQuestion($course_id, $paperId, $question, $uid);
        }

        // 04.更新总分类数量
        (new CourseQuestioncategory())->updateCateGoryAndPaper($course_id, $category_id);
    }

    private
    function saveCateQuestionByPaper($course_id, $category_id, $questionList, $uid)
    {
        // 提取全部试卷名称
        $allPaperName = array_column($questionList, 'category_1');

        // 循环创建全部试卷
        $allPaperName = array_unique($allPaperName);
        $allPaperNameDict = [];
        $model = new Coursepaper();
        foreach ($allPaperName as $paperName) {
            $allPaperNameDict[$paperName] = $model->createByName($course_id, $category_id, $paperName);
        }

        // 按照试卷进行题目分类
        $paperCategoryQuestionList = [];
        foreach ($questionList as $question) {
            $paperName = $question['category_1'];
            $paperNameId = $allPaperNameDict[$paperName];
            $paperCategoryQuestionList[$paperNameId][] = $question;
        }

        // 循环导入试卷
        foreach ($paperCategoryQuestionList as $paperId => $itemList) {

            // 循环导入题目
            foreach ($itemList as $question) {
                $this->saveQuestion($course_id, $paperId, $question, $uid);
            }

            // 更新题目数量
            $this->updateChapterQuestionCount($course_id, $paperId);
        }
    }

    /**
     * 更新试卷题目数量（公共方法）
     * @param int $course_id 课程ID
     * @param int $extend_id 试卷ID
     */
    public function updatePaperQuestionCount($course_id, $extend_id)
    {
        return $this->updateChapterQuestionCount($course_id, $extend_id);
    }


    private
    function updateChapterQuestionCount($course_id, $extend_id)
    {

        // 查询题目数量
        $model = new Question();
        $where = ['course_id' => $course_id, 'extend_id' => $extend_id];
        $questionCount = $model->where($where)->count();

        // 更新试卷题目数量
        $model = new Coursepaper();
        $model->setQuestionCount($extend_id, $questionCount);

        // 获取试卷的category_id
        $category_id = $model->where(['id' => $extend_id])->value('category_id');

        // 确保试卷关联的分类编号有效
        if (!$category_id) {
            throw new BusinessException('试卷分类ID不存在');
        }

        // 更新分类题目数量
        $model = new Coursequestioncategory();
        $model->setQuestionCountById($category_id);
    }


    private
    function saveQuestion($course_id, $extend_id, $question, $uid)
    {
        // 组装到库的数据
        $saveData = $this->cleanQuestionData($course_id, $extend_id, $question, $uid);

        // 新增数据
        $model = new Question();
        $questionId = $model->insertGetId($saveData);
        if (!$questionId) {
            throw new BusinessException('保存数据库失败');
        }
    }

    private
    function cleanQuestionData($course_id, $extend_id, $question, $uid)
    {
        // 提取题干并转换为backgroundId
        $questionBackground = $question['questionBackground'];;
        if (!empty($questionBackground)) {
            $backgroundId = CourseQuestionBackground::getBackgroundId($course_id, $questionBackground);
        }

        // 组装数据
        $time = time();
        $saveData = [
            'type' => 4,
            'course_id' => $course_id,
            'extend_id' => $extend_id,
            'question_type' => $question['questionType'],
            'question_name' => $question['questionAsk'],
            'question_data' => $this->buildQuestionJson($question),
            'background_id' => $backgroundId ?? 0,
            'uid' => $uid,
            'a_time' => $time,
            'u_time' => $time,
        ];
        return $saveData;
    }

    private
    function buildQuestionJson($question)
    {
        $data = [];
        $allKeys = ['questionAsk', 'answerOption', 'correctOption', 'explanation'];
        foreach ($allKeys as $key) {
            if (array_key_exists($key, $question)) {
                $data[$key] = $question[$key];
            }
        }
        return json_encode($data, JSON_UNESCAPED_UNICODE);
    }
}
